package com.mb.app.appused.base;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.TextView;

public class BindingTools {

	public List<View> childViews;
	public HashMap<String, String> map;
	public String debugInfo = "-----1";
	Context context;
	InvalUI invalUI;
	Object beanClass;
	public Boolean autoVisable = true;
	OnBindingListener onBindingListener;

	public BindingTools(View layout, Object data) {
		init(layout, data);
	}

	public BindingTools(Activity activity, Object data) {
		init(activity.getWindow().getDecorView(), data);
	}

	public void updateView(Boolean updata) {
		invalUI = new InvalUI(updata);
		invalUI.execute();
	}

	public void setBindingListener(OnBindingListener listener) {
		this.onBindingListener = listener;
	}

	void init(View view, Object data) {
		context = view.getContext();
		childViews = getAllChildViews(view);
		if (data == null)
			return;
		beanClass = data;
		updateView(true);
	}

	void recreat() {
		if (beanClass == null)
			return;
		if (map == null)
			map = new HashMap<String, String>();
		Field[] fields = beanClass.getClass().getFields();
		AccessibleObject.setAccessible(fields, true);
		for (Field temp : fields) {
			try {
				// temp.setAccessible(true);
				String name = temp.getName();
				String value = getFileValue(temp, beanClass);
				map.put(name, value);
			} catch (IllegalArgumentException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	List<View> getAllChildViews(View view) {
		List<View> allchildren = new ArrayList<View>();
		if (view instanceof ViewGroup) {
			ViewGroup vp = (ViewGroup) view;
			for (int i = 0; i < vp.getChildCount(); i++) {
				View viewchild = vp.getChildAt(i);
				allchildren.add(viewchild);
				allchildren.addAll(getAllChildViews(viewchild));
			}
		}
		return allchildren;
	}

	String getFileValue(Field field, Object bean) {
		if (field == null)
			return "";
		String value = "";
		try {
			Object temp = field.get(bean);
			if (temp != null)
				value = temp.toString();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return value;
	}

	/**
	 * 更新UI
	 * 
	 * @author xhwwz
	 * 
	 */
	class InvalUI extends AsyncTask<Void, Integer, Void> {

		Boolean updata = false;

		public InvalUI(Boolean updata) {
			this.updata = updata;
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
			if (onBindingListener != null)
				onBindingListener.onStart();

			binding(updata);
		}

		@Override
		protected Void doInBackground(Void... params) {
			// TODO Auto-generated method stub

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);

			if (onBindingListener != null)
				onBindingListener.onBindinged();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
			if (onBindingListener != null)
				onBindingListener.onProgress(values[0]);
		}
	}

	void binding(Boolean updata) {
		debugInfo = "";
		if (updata)
			recreat();

		if (map == null) {
			debugInfo = "\n map is Null";
			return;
		}
		if (childViews == null) {
			debugInfo = "\n childViews is Null";
			return;
		}
		debugInfo = "\n----\n";
		for (int a = 0; a < childViews.size(); a++) {
			setViewData(childViews.get(a), a);
		}
	}

	@SuppressLint("DefaultLocale")
	void setViewData(View view, int sp) {
		debugInfo += "\n  sp = " + sp;
		if (view == null || map == null)
			return;

		Object tag = view.getTag();

		if (tag == null) {
			debugInfo += "  tag = null";
			return;
		}
		debugInfo += "  tag = " + tag;

		String key = tag.toString();
		if (!map.containsKey(key)) {
			debugInfo += "  value = null";
			return;
		}
		String value = map.get(key);
		if (value == null)
			return;
		debugInfo += "  value = " + value;

		if (view instanceof CheckBox) {
			debugInfo += "  view = CheckBox";
			if (value.toLowerCase().compareTo("false") == 0) {
				((CheckBox) view).setChecked(false);
				return;
			}
			if (value.toLowerCase().compareTo("true") == 0) {
				((CheckBox) view).setChecked(true);
				return;
			}
		}

		if (view instanceof RadioButton) {
			debugInfo += "  view = RadioButton";
			if (value.toLowerCase().compareTo("false") == 0) {
				((RadioButton) view).setChecked(false);
				return;
			}
			if (value.toLowerCase().compareTo("true") == 0) {
				((RadioButton) view).setChecked(true);
				return;
			}
		}

		if (view instanceof TextView) {
			((TextView) view).setText(value);
			if (autoVisable) {
				if (value.length() < 1)
					view.setVisibility(View.GONE);
				else
					view.setVisibility(View.VISIBLE);
			}

			debugInfo += "  view = TextView";
			return;
		}

		if (view instanceof ImageView) {
			debugInfo += "  view = ImageView";
			if (isUrl(value)) {

				return;
			}
			if (isNumeric(value)) {

				return;
			}
		}
		if (view instanceof WebView) {
			debugInfo += "  view = WebView";
			if (isUrl(value))
				((WebView) view).loadUrl(value);
			return;
		}

		if (view instanceof ProgressBar) {
			debugInfo += "  view = ProgressBar";
			if (isNumeric(value)) {
				int p = Integer.parseInt(value);
				((ProgressBar) view).setProgress(p);
			}
			return;
		}
	}

	/**
	 * 判断是否为数
	 * 
	 * @param str
	 * @return
	 */
	static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	/**
	 * 判断为Email
	 * 
	 * @param str
	 * @return
	 */
	static boolean isEmail(String str) {
		String regEx = "[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}";
		Pattern pattern = Pattern.compile(regEx);
		Matcher matcher = pattern.matcher(str);
		boolean rs = matcher.matches();
		return rs;
	}

	/**
	 * 判断是否URL
	 * 
	 * @param str
	 * @return
	 */
	static boolean isUrl(String str) {
		String regEx = "^([hH][tT]{2}[pP]://|[hH][tT]{2}[pP][sS]://)(([A-Za-z0-9-~]+).)+([A-Za-z0-9-~\\/])+$";
		Pattern pattern = Pattern.compile(regEx);
		Matcher matcher = pattern.matcher(str);
		boolean rs = matcher.matches();
		return rs;
	}

	/**
	 * 通过名称读取ID
	 * 
	 * @param name
	 * @return
	 */
	int getId(String name) {
		int idFlag = context.getResources().getIdentifier(name, "drawable",
				context.getPackageName());
		return idFlag;
	}

	public interface OnBindingListener {
		public void onStart();

		public void onBindinged();

		public void onProgress(int p);
	}
}